import type { Tab } from '#/browser/entities/tab.entity'
import type { BaseWindow } from 'electron'
import type { CreateState } from 'global-state'
import type { WindowState } from '~types/global-state'
import { TypedEventEmitter } from '#/utils/events'
import { calculateWindowDimensions } from '#/utils/paths'
import { getSeparateLayoutTab } from '#/utils/tabs'
import { createBaseWindow } from '#/utils/windows'
import { createStorageState } from 'global-state'
import { WINDOW_STYLE_CONSTANTS } from '~shared/constants/layout'
import { createBrowserIpc } from '#/utils/ipc'

import { installSeparateShortcuts } from '#/browser/services/shortcut.installer'

type Events = {
  closed: () => void // 标签页关闭时触发
  shown: () => void // 窗口显示/还原
  hidden: () => void // 窗口隐藏/最小化
}

/**
 * @file 单独窗口控制器
 * @description
 * @author 黄敏
 * @since 2025-08-26 15:23
 */
export class SeparateController extends TypedEventEmitter<Events> {
  private readonly parentWindow: BaseWindow
  private readonly electronWindow: BaseWindow
  private readonly tab: Tab
  private readonly layoutTab: Tab
  private readonly store: CreateState<WindowState>
  private readonly boundUpdateData: (data: F2.tab.Patch) => void
  private readonly boundOnShow: () => void
  private readonly boundOnHide: () => void
  private readonly boundOnMinimize: () => void
  private readonly boundOnRestore: () => void

  private readonly boundUpdateWindowBoundary: () => void

  private browserIpc!: ReturnType<typeof createBrowserIpc>

  get data() {
    return this.tab.data
  }

  get tabId() {
    return this.tab.data.id
  }

  get view() {
    return this.tab.view
  }

  constructor(tab: Tab, parentWindow: BaseWindow, type: F2.tab.ControllerType) {
    super()
    this.tab = tab
    this.parentWindow = parentWindow

    // 绑定方法引用，确保监听和取消监听使用相同的函数引用
    this.boundUpdateData = this.updateData.bind(this)
    this.boundUpdateWindowBoundary = this.updateWindowBoundary.bind(this)

    //
    this.boundOnShow = () => this.emit('shown')
    this.boundOnHide = () => this.emit('hidden')
    this.boundOnMinimize = this.boundOnHide
    this.boundOnRestore = this.boundOnShow
    const { width, height } = calculateWindowDimensions(parentWindow)

    this.store = createStorageState(
      `separateBounds-${this.tab.data.id}`,
      {
        width:
          this.tab.separateConfig?.width ??
          (type === 'right' ? WINDOW_STYLE_CONSTANTS.SIDEBAR_VIEW_DEFAULT_WIDTH : width - 40),
        height: this.tab.separateConfig ?? height - 40,
        isMaximized: false
      } as WindowState,
      1,
      { skipDefaultsCheck: true }
    )

    /**
     * 当有配置窗口大小时，优先使用配置的窗口大小
     * */
    if (this.tab.separateConfig) {
      if (this.store.state.isMaximized) {
        this.store.set('isMaximized', false)
      }
      if (this.tab.separateConfig.width !== this.store.state.width) {
        this.store.set('width', this.tab.separateConfig.width)
        this.store.set('height', this.tab.separateConfig.height)
      }
    }

    this.electronWindow = createBaseWindow(this.store, {
      frame: false,
      show: false,
      parent: parentWindow
    })
    this.layoutTab = getSeparateLayoutTab(tab.webContentsId)

    this.browserIpc = createBrowserIpc(this.layoutTab.view.webContents)

    this.electronWindow.contentView.addChildView(this.layoutTab.view)

    this.electronWindow.on('show', this.boundOnShow)
    this.electronWindow.on('hide', this.boundOnHide)
    this.electronWindow.on('minimize', this.boundOnMinimize)
    this.electronWindow.on('restore', this.boundOnRestore)

    this.electronWindow.contentView.addChildView(this.tab.view)
    this.updateWindowBoundary()

    // 使用绑定后的方法引用监听事件
    this.electronWindow.on('resize', this.boundUpdateWindowBoundary)
    this.electronWindow.on('maximize', this.boundUpdateWindowBoundary)
    this.electronWindow.on('unmaximize', this.boundUpdateWindowBoundary)

    this.setupMessageHandlers()

    // 安装该独立窗口内的快捷键（包含查找、导航、刷新、DevTools、关闭）
    installSeparateShortcuts({
      win: this.electronWindow,
      layoutTab: this.layoutTab,
      contentTab: this.tab
    })

    this.tab.on('data:change', this.boundUpdateData)
    this.tab.on('closed', () => {
      console.log('标签页关闭，关闭独立窗口')
      this.close()
    })
    this.tab.on('separate-config:change', config => {
      if (!config) return
      this.store.set('width', config.width)
      this.store.set('height', config.height)
      this.electronWindow.setSize(config.width, config.height, true)
    })

    setImmediate(() => {
      this.electronWindow.focus()
    })
  }

  // data 更新
  updateData(data: F2.tab.Patch) {
    this.browserIpc.send('separate:update', data)
  }

  private setupMessageHandlers(): void {
    this.browserIpc.on('hideTab', () => {
      this.minimize()
    })

    this.browserIpc.syncOn('isWindowMaximized', () => {
      return this.electronWindow.isMaximized()
    })

    // 窗口控制
    this.browserIpc.on('minimizeWindow', () => {
      this.electronWindow.minimize()
    })

    this.browserIpc.on('maximizeWindow', () => {
      this.electronWindow.maximize()
    })

    this.browserIpc.on('unmaximizeWindow', () => {
      this.electronWindow.unmaximize()
    })

    this.browserIpc.on('setLayer', isOnTop => {
      if (isOnTop) {
        // 移动到顶层（最后添加的视图在最上层）
        this.electronWindow.contentView.addChildView(this.layoutTab.view)
      } else {
        // 移动到底层（索引0为最底层）
        this.electronWindow.contentView.addChildView(this.layoutTab.view, 0)
      }
    })
  }

  updateWindowBoundary() {
    const { width, height } = calculateWindowDimensions(this.electronWindow)
    // layout顶部高度
    const topHeight = 32
    // 四周间留白
    const padding = 5
    this.layoutTab.view.setBounds({ x: 0, y: 0, width, height })
    this.view.setBounds({
      x: padding,
      y: topHeight,
      width: width - padding * 2,
      height: height - topHeight - padding
    })

    this.browserIpc.send('window:maximize-state', this.electronWindow.isMaximized())
  }

  /**
   * 打开窗口，如果最小化则还原，如果隐藏则显示，如果已经在显示则聚焦，如果已经显示并已经聚焦则无操作
   * */
  open() {
    if (this.electronWindow.isMinimized()) {
      this.electronWindow.restore()
    } else if (!this.electronWindow.isVisible()) {
      this.electronWindow.show()
    }

    setImmediate(() => {
      this.electronWindow.focus()
    })
  }

  // 隐藏窗口
  minimize() {
    if (this.electronWindow.getParentWindow()) {
      this.electronWindow.hide()
    } else {
      this.electronWindow.minimize()
    }
  }

  /**
   * 销毁窗口
   * */
  close() {
    // 使用相同的绑定引用取消监听
    this.tab.off('data:change', this.boundUpdateData)
    this.electronWindow.off('resize', this.boundUpdateWindowBoundary)
    this.electronWindow.off('maximize', this.boundUpdateWindowBoundary)
    this.electronWindow.off('unmaximize', this.boundUpdateWindowBoundary)
    this.electronWindow.off('show', this.boundOnShow)
    this.electronWindow.off('hide', this.boundOnHide)
    this.electronWindow.off('minimize', this.boundOnMinimize)
    this.electronWindow.off('restore', this.boundOnRestore)

    this.store.destroy()
    this.parentWindow.focus()

    // this.tab.destroy(),tab销毁的逻辑在tabController中处理，这里不能处理
    this.layoutTab.destroy()
    this.electronWindow.destroy()
    this.emit('closed')
  }
}
